<?php
declare(strict_types=1);
/**
 * Created by PhpStorm
 * User: Administrator
 * Date: 2023/8/7
 * Time: 11:06:49
 */

namespace Service\CommodityService;

use Service\Code\Normal;
use App\Model\BbcModel\TransitTemplate;
use App\Model\BbcModel\TransitRule;
use App\Model\BbcModel\TransitArea;
use Hyperf\DbConnection\Db;
use Service\BaseService;
use App\Model\BbcModel\Area;

/**
 * 运费模板管理
 */
class ExpressService extends BaseService
{
    public function expressList(array $param) 
    {
        $page = $param['page'] ?? 1;
        $limit = $param['limit'] ?? 10;

        $where = [
            ['cid','=',$param['cid']],
            ['df','=',0]
        ];
        if(isset($page['name']) && $param['name'] != ''){
            $where[] = ['name','like',"%{$param['name']}%"];
        }

        $data_list = TransitTemplate::instance()
            ->where($where)
            ->paginate($limit,['id','name','up as md','status'],'page',$page);

        $list = $data_list->items();
        $total = $data_list->total();

        foreach ($list as &$v){
            if($v['md']){
                $v['md'] = date('Y-m-d H:i:s',$v['md']);
            }else{
                $v['md'] = '';
            }

            //可下单规则
            $y_rule = TransitRule::instance()
                ->where(['template_id'=>$v['id']])
                ->select(['id','first_weight','first_price','unit_weight','unit_price'])
                ->get()->toArray();

            //可下单地区
            $y_area = TransitArea::instance()
                ->join('ly_area','ly_area.id','=','ly_transit_area.area_id')
                ->where(['ly_transit_area.template_id'=>$v['id'],'ly_transit_area.type'=>1])
                ->select(['ly_area.name','ly_transit_area.rule_id'])
                ->get()->toArray();

            $y_area_map = getArrayGroupData($y_area,'rule_id');

            foreach ($y_rule as &$val){
                $y_area_map_current = $y_area_map[$val['id']]; //当前规则的地区
                $area_name_arr = array_column($y_area_map_current,'name');
                $area_name_str = implode(',',$area_name_arr);
                $val['area'] = $area_name_str;
            }
            $v['y_rule'] = $y_rule;

            //不可下单地区
            $n_area = TransitArea::instance()
                ->join('ly_area','ly_area.id','=','ly_transit_area.area_id')
                ->where(['ly_transit_area.template_id'=>$v['id'],'ly_transit_area.type'=>2])
                ->pluck('ly_area.name')->toArray();
            $n_area = array_filter($n_area);
            if($n_area){
                $area = implode(',',$n_area);
            }else{
                $area = '';
            }
            $v['n_rule'] = ['area'=>$area];
        }

        return Normal::returnCode(Normal::SUC,'请求成功',['list'=>$list,'total'=>$total]);
    }

    /**
     * 新增运费模板
     * @param $param
     * @return array
     */
    public function addExpressTemplate(array $param)
    {
        if(!isset($param['name']) || !$param['name']){
            return Normal::returnCode(Normal::FAIL,'模板名称不能为空');
        }

        if(mb_strlen($param['name']) >= 20){
            return Normal::returnCode(Normal::FAIL,'模板名称20字以内');
        }

        $area = [];
        if(isset($param['yes_buy_area']) && $param['yes_buy_area']){ //设置了可下单地区
            $area_arr = array_column($param['yes_buy_area'],'area_ids');
            foreach ($area_arr as $val){
                foreach ($val as $v){
                    $area[] = $v;
                }
            }
        }
        if(isset($param['no_buy_area']) && $param['no_buy_area']){ //设置了不可下单地区
            $area_arr = array_column($param['no_buy_area'],'area_ids');
            foreach ($area_arr as $val){
                foreach ($val as $v){
                    $area[] = $v;
                }
            }
        }
        $repeat_arr = $this->fetchRepeatMemberInArray($area);
        $str = [];
        if($repeat_arr){
            foreach($repeat_arr as $v){
                $str[] = Area::instance()->where(['id'=>$v])->value('name');
            }
            $str = implode(',',$str);
            return Normal::returnCode(Normal::FAIL,$str.'重复');
        }
        Db::connection('bbc_commodity')->beginTransaction();
        try{
            $template_id = TransitTemplate::instance()
                ->insertGetId([
                    'name'   => $param['name'],
                    'sid'    => $param['sid'],
                    'cid'    => $param['cid'],
                    'status' => 0,
                    'cd'     => time(),
                    'up'     => time(),
                ]);
            if(isset($param['yes_buy_area']) && $param['yes_buy_area']){ //设置了运费模板
                $this->yes_buy_area($param,$template_id);
            }

            if(isset($param['no_buy_area']) && $param['no_buy_area']){ //设置了不可下单地区
                $this->no_buy_area($param,$template_id);
            }
            Db::connection('bbc_commodity')->commit();
        }catch (\Exception $e){
            Db::connection('bbc_commodity')->rollBack();
            return Normal::returnCode(Normal::FAIL,'新增失败：'.$e->getMessage());
        }

        return Normal::returnCode(Normal::SUC,'请求成功');
    }

    /**
     * 指定地区运费模板
     * @param $param
     * @return void
     * @throws \Exception
     */
    public function yes_buy_area($param,$template_id)
    {
        $yes_buy_area = $param['yes_buy_area'];

        foreach ($yes_buy_area as $key=>$val){
            if(!isset($val['area_ids']) || !$val['area_ids']){
                throw new \Exception('请选择地区');
            }

            if(!isset($val['first_weight']) || !$val['first_weight']){
                throw new \Exception('请填写首重');
            }

            $val['first_weight'] = $val['first_weight']*1000;
            if((floor($val['first_weight']) - $val['first_weight']) !=0){
                throw new \Exception('首重最多三位小数');
            }
            if(!isset($val['unit_weight']) || !$val['unit_weight']){
                throw new \Exception('请填写增加的重量');
            }
            $val['unit_weight'] = $val['unit_weight']*1000;
            if((floor($val['unit_weight']) - $val['unit_weight']) !=0){
                throw new \Exception('增加的重量最多三位小数');
            }

            if($val['first_weight'] < 0){
                throw new \Exception('首重不能小于0');
            }
            if($val['first_price'] < 0){
                throw new \Exception('首重运费不能小于0');
            }
            if($val['unit_weight'] < 0){
                throw new \Exception('增加重量不能小于0');
            }
            if($val['unit_price'] < 0){
                throw new \Exception('增加重量运费不能小于0');
            }

            $insert_rule_data['first_weight'] = $val['first_weight'];
            $insert_rule_data['first_price']  = $val['first_price'];
            $insert_rule_data['unit_weight']  = $val['unit_weight'];
            $insert_rule_data['unit_price']   = $val['unit_price'];
            $insert_rule_data['sid']          = $param['sid'];
            $insert_rule_data['cid']          = $param['cid'];
            $insert_rule_data['template_id']  = $template_id;
            $insert_rule_data['cd']           = time();

            $rule_id = TransitRule::instance()->insertGetId($insert_rule_data);

            $insert_area_data = [];
            foreach($val['area_ids'] as $v){
                $insert_area_data[] = [
                    'sid'         => $param['sid'],
                    'cid'         => $param['cid'],
                    'area_id'     => $v,
                    'rule_id'     => $rule_id,
                    'cd'          => time(),
                    'type'        => 1,
                    'template_id' => $template_id
                ];
            }
            TransitArea::instance()
                ->insert($insert_area_data);

        }
    }

    /**
     * 不可下单地区
     * @param $param
     * @return void
     * @throws \Exception
     */
    public function no_buy_area($param,$template_id)
    {
        $no_buy_area = $param['no_buy_area'];
        if(!isset($no_buy_area['area_ids']) || !$no_buy_area['area_ids']){
            throw new \Exception('请选择不可下单地区');
        }
        $insert_no_appoint_data = [];
        foreach($no_buy_area['area_ids'] as $val){
            $insert_no_appoint_data[] = [
                'sid'         => $param['sid'],
                'cid'         => $param['cid'],
                'area_id'     => $val,
                'cd'          => time(),
                'type'        => 2,
                'template_id' => $template_id
            ];
        }

        TransitArea::instance()->insert($insert_no_appoint_data);
    }

    /**
     * 获取地区重复的地区
     * @param [type] $array [description]
     */
    public function fetchRepeatMemberInArray($array)
    {
        // 获取去掉重复数据的数组
        $unique_arr = array_unique ( $array );
        // 获取重复数据的数组
        return array_diff_assoc ( $array, $unique_arr );
    }

    /**
     * 运费模板详情
     */
    public function expressTemplateDetails(array $param)
    {
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'缺少运费模板ID');
        }

        $info = TransitTemplate::instance()
            ->where(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0])
            ->first();
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'模板不存在');
        }
        $data['id']     = $info['id'];
        $data['name']   = $info['name'];
        $data['status'] = $info['status'];
        $rule = TransitRule::instance()
            ->where(['template_id'=>$info['id']])
            ->select(['id','first_weight','first_price','unit_weight','unit_price'])
            ->get()->toArray();
        foreach($rule as $k=>$v){
            $rule[$k]['area_list'] = TransitArea::instance()
                ->join('ly_area','ly_area.id','=','ly_transit_area.area_id')
                ->where(['ly_transit_area.rule_id'=>$v['id']])
                ->pluck('ly_area.name')->toArray();
        }
        $data['no_buy_area'] = TransitArea::instance()
            ->leftJoin('ly_area','ly_area.id','=','ly_transit_area.area_id')
            ->where(['ly_transit_area.type'=>2,'template_id'=>$info['id']])
            ->pluck('ly_area.name')->toArray();
        $data['yes_buy_area'] = $rule;
        return Normal::returnCode(Normal::SUC,'请求成功',$data);
    }

    public function editExpressTemplate(array $param)
    {
        if(!isset($param['id']) || !$param['id']){
            return Normal::returnCode(Normal::FAIL,'缺少运费模板ID');
        }
        if(!isset($param['name']) || !$param['name']){
            return Normal::returnCode(Normal::FAIL,'模板名称不能为空');
        }

        if(mb_strlen($param['name']) >= 20){
            return Normal::returnCode(Normal::FAIL,'模板名称20字以内');
        }


        $info = TransitTemplate::instance()
            ->where(['id'=>$param['id'],'cid'=>$param['cid'],'df'=>0])
            ->exists();
        if(!$info){
            return Normal::returnCode(Normal::FAIL,'模板不存在');
        }
        Db::beginTransaction();
        try{
            $template_id = $param['id'];
            TransitTemplate::instance()
                ->where(['id'=>$param['id']])
                ->update([
                    'name'   => $param['name'],
                    'up'     => time(),
                ]);
            TransitRule::instance()->where(['template_id'=>$template_id])->delete();
            TransitArea::instance()->where(['template_id'=>$template_id])->delete();
            if(isset($param['yes_buy_area']) && $param['yes_buy_area']){ //设置了运费模板
                $this->yes_buy_area($param,$template_id);
            }

            if(isset($param['no_buy_area']) && $param['no_buy_area']){ //设置了不可下单地区
                $this->no_buy_area($param,$template_id);
            }
            Db::commit();
        }catch (\Exception $e){
            Db::rollBack();
            return Normal::returnCode(Normal::FAIL,'编辑失败'.$e->getMessage());
        }

        return Normal::returnCode(Normal::SUC,'编辑成功');
    }

    public function areaList($param) :array{
        $data_str = redis()->get('Area_All_Region');
        if(empty($data_str)){
            $fields = ['id','pid','name'];
            $area = Area::instance()->select($fields)->where('pid',0)->get();
            $data = [];
            foreach ($area as $key => $value) {
                $son1 = Area::instance()->select($fields)->where('pid',$value['id'])->get();
                $son = [];
                foreach ($son1 as $k => $v) {
                    $ship_num = 0;
                    $son2 = Area::instance()->select($fields)->where('pid',$v['id'])->get();
                    foreach ($son2 as $ka => $va) {
                        if($va['is_ship']==1){
                            $ship_num++;
                        }
                    }
                    $son[] = array('name' =>$v['name'] ,'id'=>$v['id'],'is_ship'=>$v['is_ship'],'ship_num'=>$ship_num,'son'=>$son2 );
                }
                $data[$value['id']] = array('name' =>$value['name'] ,'id'=>$value['id'],'is_ship'=>$value['is_ship'],'son'=>$son );
            }
            $data = array_values($data);
            $data_str = json_encode($data);
            redis()->set('Area_All_Region', $data_str,300);
        }else{
            $data = json_decode($data_str,true);
        }

        return Normal::returnCode(Normal::SUC,'请求成功',$data);
    }
}